package com.atguigu.gmall.cart.config;

import com.atguigu.gmall.cart.interceptor.LoginInterceptor;
import com.atguigu.gmall.common.consts.GmallConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.AsyncConfigurer;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;

@Configuration
@Slf4j
public class GmallCartAsyncConfig implements AsyncConfigurer {
    @Resource
    StringRedisTemplate stringRedisTemplate;
    //给Async框架配置自定义的线程池，如果不配置 使用自己默认的线程池
    @Override
    public Executor getAsyncExecutor() {
        return null;
    }
    //给Async框架提供异常处理器：当异步任务执行出现异常时 异常处理器会生效
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {
            log.error("方法：{} 执行出现异常：{}，参数列表: {}" , method,throwable.getMessage(),
                    ArrayUtils.toString(objects));
            //获取数据库操作失败的userId/userKey 存到redis中失败列表中
            //List
//            LoginInterceptor.userInfo().一定获取不到用户信息
            if(ArrayUtils.isEmpty(objects)){
                return;
            }
            //获取异步任务执行失败的参数列表中的第一个(统一都设置为了userKey)
            String userKey = objects[0].toString();
            BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(GmallConsts.CART_ASYNCFAIL_USERIDS);
            listOps.leftPush(userKey);//左进
        };
    }
}
